package com.begamer.card.controller;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.begamer.card.cache.Cache;
import com.begamer.card.cache.PlayerInfo;
import com.begamer.card.common.Constant;
import com.begamer.card.common.util.EncryptAndDecipher;
import com.begamer.card.common.util.GmSpecialMailUtil;
import com.begamer.card.common.util.Random;
import com.begamer.card.common.util.RequestUtil;
import com.begamer.card.common.util.Statics;
import com.begamer.card.common.util.StringUtil;
import com.begamer.card.common.util.binRead.BinReader;
import com.begamer.card.common.util.binRead.CardData;
import com.begamer.card.common.util.binRead.CardExpData;
import com.begamer.card.common.util.binRead.MazeBattleData;
import com.begamer.card.common.util.binRead.MazeData;
import com.begamer.card.common.util.binRead.MissionData;
import com.begamer.card.common.util.binRead.PlayerData;
import com.begamer.card.common.util.binRead.SkillData;
import com.begamer.card.common.util.binRead.UnLockData;
import com.begamer.card.json.command2.BattleLogJson;
import com.begamer.card.json.command2.BattleLogResultJson;
import com.begamer.card.json.command2.MazeBattleLogJson;
import com.begamer.card.json.command2.MazeBattleLogResultJson;
import com.begamer.card.log.BattleCheckLogger;
import com.begamer.card.log.ErrorLogger;
import com.begamer.card.log.PlayerLogger;
import com.begamer.card.model.pojo.Card;
import com.begamer.card.model.pojo.Maze;
import com.begamer.card.model.pojo.Skill;

/**
 * 战斗
 * 
 * @author LiTao 2013-11-12 上午09:56:05
 */
public class BattleController extends AbstractMultiActionController {
	private static Logger logger = Logger.getLogger(BattleController.class);
	private static Logger playlogger = PlayerLogger.logger;
	private static Logger errorlogger = ErrorLogger.logger;
	private static Logger battleCheckLogger = BattleCheckLogger.logger;
	/** 校验战报程度0-100 **/
	private static int checkPro = 100;
	
	public ModelAndView battleOver(HttpServletRequest request, HttpServletResponse response)
	{
		try
		{
			// 校验密钥
			ModelAndView checkResult = RequestUtil.check(request);
			if (checkResult != null)
			{
				return checkResult;
			}
			// 获取json
			JSONObject jsonObject = RequestUtil.getJsonObject(request);
			// 获取参数
			BattleLogJson blj = JSONObject.toJavaObject(jsonObject, BattleLogJson.class);
			BattleLogResultJson blrj = new BattleLogResultJson();
			if (blj != null)
			{
				blrj.r = blj.r;
				PlayerInfo pi = Cache.getInstance().getPlayerInfo(blj.playerId, request.getSession());
				if (pi != null)
				{
					if (blj.r == 3)// 新手演示战斗结束
					{
						// 修改数据库
						pi.player.setNewPlayerType(1);
					}
					else
					{
						int bNum = blj.bNum;
						if (pi.bNum < bNum && pi.brj.bNum == bNum)// 第一次请求
						{
							boolean isRight = true;
							// 概率校验
							int roll = Random.getNumber(100);
							if (roll < checkPro)
							{
								isRight = Statics.checkBattleLog(pi.brj, blj);
								if (!isRight)
								{
									battleCheckLogger.error("推图校验出错:" + JSON.toJSONString(blj));
									isRight = true;
								}
							}
							// 如果校验正确,加入奖励
							if (isRight)
							{
								MissionData md = MissionData.getMissionData(pi.brj.md);
								if (md.missiontype == 1)
								{
									ActivityController.updateTaskComplete(1, pi, 1);
									pi.player.addActive(1, 1);
								}
								else if (md.missiontype == 2)
								{
									ActivityController.updateTaskComplete(1, pi, 1);
									ActivityController.updateTaskComplete(2, pi, 1);
									pi.player.addActive(1, 1);
									pi.player.addActive(2, 1);
								}
								/** 如果胜利 **/
								if (blj.r == 1)
								{
									List<Integer> cardIds = new ArrayList<Integer>();
									// 设置已完成的missionId
									if (md.missiontype == 1 && md.id > pi.player.getMissionId())
									{
										pi.player.setMissionId(md.id);
										pi.player.updateAchieve(2, md.id + "");
										String times1 = pi.player.getTimes1();
										times1 += "00";
										pi.player.setTimes1(times1);
										
										// 记录购买次数
										String buyPveEntryTimes1 = pi.player.getBuyPveEntryTimes1();
										buyPveEntryTimes1 = buyPveEntryTimes1 + "00";
										pi.player.setBuyPveEntryTimes1(buyPveEntryTimes1);
										
										// 设置解锁精英本
										UnLockData lockData = UnLockData.getUnLockData(15);
										if (lockData.method == md.id && lockData.type == 1)
										{
											pi.player.setMissionId2(Constant.PveMissionType2);
											pi.player.setTimes2("00");
											String buyPveEntryTimes2 = pi.player.getBuyPveEntryTimes2();
											buyPveEntryTimes2 = buyPveEntryTimes2 + "00";
											pi.player.setBuyPveEntryTimes2(buyPveEntryTimes2);
										}
									}
									if (md.missiontype == 2 && md.id > pi.player.getMissionId2())
									{
										pi.player.setMissionId2(md.id);
										pi.player.updateAchieve(2, md.id + "");
										String times2 = pi.player.getTimes2();
										times2 += "00";
										pi.player.setTimes2(times2);
										// 记录购买次数,2位字符来表示
										String buyPveEntryTimes2 = pi.player.getBuyPveEntryTimes2();
										buyPveEntryTimes2 = buyPveEntryTimes2 + "00";
										pi.player.setBuyPveEntryTimes2(buyPveEntryTimes2);
										
									}
									
									// 设置星级
									int star = blj.sNum;
									int sequence = md.getSequence();
									if (md.missiontype == 1)
									{
										String starLevel = pi.player.getCompleteStar1();
										if (starLevel.length() < sequence)
										{
											pi.player.setCompleteStar1(starLevel + "" + star);
										}
										else
										{
											int oldStar = StringUtil.getInt(StringUtil.getStr(starLevel, sequence - 1));
											if (star > oldStar)
											{
												pi.player.setCompleteStar1(StringUtil.replaceStr(starLevel, sequence - 1, star + ""));
											}
										}
									}
									else if (md.missiontype == 2)
									{
										String starLevel = pi.player.getCompleteStar2();
										if (starLevel.length() < sequence)
										{
											pi.player.setCompleteStar2(starLevel + "" + star);
										}
										else
										{
											int oldStar = StringUtil.getInt(StringUtil.getStr(starLevel, sequence - 1));
											if (star > oldStar)
											{
												pi.player.setCompleteStar2(StringUtil.replaceStr(starLevel, sequence - 1, star + ""));
											}
										}
									}
									// 更新成就
									if (star == 3)
									{
										pi.player.updateAchieve(3, md.map + "," + md.zone + "," + md.missiontype);
									}
									// 判断KO
									boolean verifyBonus = false;
									if (md.addtasktype > 0 && pi.brj.bs == 0)
									{
										int condition = md.addtaskid;
										switch (md.addtasktype)
										{
											case 1:// 使用合体技击杀最后一个敌人
												verifyBonus = (blj.bonus == 1);
												break;
											case 2:// 队伍中拥有指定星级卡牌
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null)
													{
														CardData cd = CardData.getData(c.getCardId());
														if (cd != null && cd.star == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
											case 3:// 不使用指定星级卡牌
												verifyBonus = true;
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null)
													{
														CardData cd = CardData.getData(c.getCardId());
														if (cd != null && cd.star == condition)
														{
															verifyBonus = false;
															break;
														}
													}
												}
												break;
											case 4:// 队伍中拥有指定种族卡牌
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null)
													{
														CardData cd = CardData.getData(c.getCardId());
														if (cd != null && cd.race == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
											case 5:// 不使用指定种族卡牌
												verifyBonus = true;
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null)
													{
														CardData cd = CardData.getData(c.getCardId());
														if (cd != null && cd.race == condition)
														{
															verifyBonus = false;
															break;
														}
													}
												}
												break;
											case 6:// 队伍中拥有指定卡牌
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null && c.getCardId() == condition)
													{
														verifyBonus = true;
														break;
													}
												}
												break;
											case 7:// 不使用指定卡牌
												verifyBonus = true;
												for (Card c : pi.getCardGroup().cards)
												{
													if (c != null && c.getCardId() == condition)
													{
														verifyBonus = false;
														break;
													}
												}
												break;
											case 8:// 队伍中拥有指定类型技能
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														SkillData sd = SkillData.getData(skillId);
														if (sd != null && sd.type == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
											case 9:// 不使用指定类型技能
												verifyBonus = true;
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														SkillData sd = SkillData.getData(skillId);
														if (sd != null && sd.type == condition)
														{
															verifyBonus = false;
															break;
														}
													}
												}
												break;
											case 10:// 队伍中拥有指定属性技能
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														SkillData sd = SkillData.getData(skillId);
														if (sd != null && sd.element == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
											case 11:// 不使用指定属性技能
												verifyBonus = true;
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														SkillData sd = SkillData.getData(skillId);
														if (sd != null && sd.element == condition)
														{
															verifyBonus = false;
															break;
														}
													}
												}
												break;
											case 12:// 队伍中拥有指定技能
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														if (skillId == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
											case 13:// 不使用指定技能
												verifyBonus = true;
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														if (skillId == condition)
														{
															verifyBonus = false;
															break;
														}
													}
												}
												break;
											case 14:// 规定回合数胜利
												verifyBonus = (blj.round <= condition);
												break;
											case 15:// 队伍中拥有指定星级技能
												for (int k = 0; k < pi.getCardGroup().cards.length; k++)
												{
													Card c = pi.getCardGroup().cards[k];
													if (c != null)
													{
														Skill s = pi.getCardGroup().skills[k];
														int skillId = 0;
														if (s != null)
														{
															skillId = s.getSkillId();
														}
														else
														{
															skillId = CardData.getData(c.getCardId()).basicskill;
														}
														SkillData sd = SkillData.getData(skillId);
														if (sd != null && sd.star == condition)
														{
															verifyBonus = true;
															break;
														}
													}
												}
												break;
										}
									}
									// 满足bonus条件
									if (verifyBonus)
									{
										MissionData mData = MissionData.getMissionData(pi.brj.md);
										pi.player.setKopoint(pi.player.getKopoint() + mData.kopoint);
										// ko积分达到n发奖励
										GmSpecialMailUtil.getInstance().saveKopointLog(pi.player.getId(), pi.player.getName(), pi.player.getLevel(), mData.kopoint);
										// 将物品发放至背包
										if (mData.specialtype1 != 0 && mData.specialaward1.length() > 0)
										{
											if (mData.specialtype1 == 3)
											{
												String[] temp = mData.specialaward1.split(",");
												cardIds.add(StringUtil.getInt(temp[0]));
											}
											bonusAward(mData.specialtype1, mData.specialaward1, pi);
										}
										if (mData.specialtype2 != 0 && mData.specialaward2.length() > 0)
										{
											if (mData.specialtype2 == 3)
											{
												String[] temp = mData.specialaward2.split(",");
												cardIds.add(StringUtil.getInt(temp[0]));
											}
											bonusAward(mData.specialtype2, mData.specialaward2, pi);
										}
										// 修改数据库bonus标识
										if (md.missiontype == 1)
										{
											String str = pi.player.getBouns1();
											if (str.length() < sequence)
											{
												pi.player.setBouns1(str + "" + 1);
											}
											else
											{
												int oldStr = StringUtil.getInt(StringUtil.getStr(str, sequence - 1));
												if (oldStr == 0)
												{
													pi.player.setBouns1(StringUtil.replaceStr(str, sequence - 1, 1 + ""));
												}
											}
										}
										else if (md.missiontype == 2)
										{
											String str = pi.player.getBouns2();
											if (str.length() < sequence)
											{
												pi.player.setBouns2(str + "" + 1);
											}
											else
											{
												int oldStr = StringUtil.getInt(StringUtil.getStr(str, sequence - 1));
												if (oldStr == 0)
												{
													pi.player.setBouns2(StringUtil.replaceStr(str, sequence - 1, 1 + ""));
												}
											}
										}
										playlogger.info("|区服：" + Cache.getInstance().serverId + "|玩家：" + pi.player.getId() + "|" + pi.player.getName() + "|领取KO奖励|" + pi.brj.md);
										// 更新成就
										pi.player.updateAchieve(4, null);
									}
									else
									{
										if (md.missiontype == 1)
										{
											String str = pi.player.getBouns1();
											if (str.length() < sequence)
											{
												pi.player.setBouns1(str + "" + 0);
											}
										}
										else if (md.missiontype == 2)
										{
											String str = pi.player.getBouns2();
											if (str.length() < sequence)
											{
												pi.player.setBouns2(str + "" + 0);
											}
										}
									}
									// 战前玩家信息
									blrj.lv0 = pi.player.getLevel();
									blrj.ce0 = pi.player.getCurExp();
									PlayerData pd = PlayerData.getData(pi.player.getLevel() + 1);
									if (pd != null)
									{
										blrj.me0 = pd.exp;
									}
									// 战斗胜利后扣除体力
									pi.player.removePower(md.cost);
									blrj.power0 = pi.player.getPower();
									// 玩家获得经验
									pi.player.addExp(md.personexp);
									// 玩家获得金币
									int gold = (int) (md.coins * Float.valueOf(blj.gm));
									pi.player.addGold((int) Cache.getGoldDropMul() * gold);
									// 战后玩家信息
									blrj.lv1 = pi.player.getLevel();
									blrj.ce1 = pi.player.getCurExp();
									blrj.power1 = pi.player.getPower();
									pd = PlayerData.getData(pi.player.getLevel() + 1);
									if (pd != null)
									{
										blrj.me1 = pd.exp;
									}
									// 战前/战后角色卡信息,格式:cardId-level-curExp-maxExp-hp-atk-def
									List<String> cards0 = new ArrayList<String>();
									List<String> cards1 = new ArrayList<String>();
									for (Card c : pi.getCardGroup().cards)
									{
										if (c != null)
										{
											CardData cd = CardData.getData(c.getCardId());
											// 战前
											int maxExp = 0;
											CardExpData ced = CardExpData.getData(c.getLevel() + 1);
											if (cd != null && ced != null)
											{
												maxExp = ced.starexps[cd.star - 1];
											}
											int maxHp = (int) Statics.getCardSelfMaxHp(c.getCardId(), c.getLevel(), c.getBreakNum());
											int atk = (int) Statics.getCardSelfMaxAtk(cd.id, c.getLevel(), c.getBreakNum());
											int def = (int) Statics.getCardSelfMaxDef(cd.id, c.getLevel(), c.getBreakNum());
											cards0.add(c.getCardId() + "-" + c.getLevel() + "-" + c.getCurExp() + "-" + maxExp + "-" + maxHp + "-" + atk + "-" + def);
											// 角色卡获得经验
											c.addExp(md.cardexp);
											// 战后
											ced = CardExpData.getData(c.getLevel() + 1);
											if (cd != null && ced != null)
											{
												maxExp = ced.starexps[cd.star - 1];
											}
											maxHp = (int) Statics.getCardSelfMaxHp(c.getCardId(), c.getLevel(), c.getBreakNum());
											atk = (int) Statics.getCardSelfMaxAtk(cd.id, c.getLevel(), c.getBreakNum());
											def = (int) Statics.getCardSelfMaxDef(cd.id, c.getLevel(), c.getBreakNum());
											cards1.add(c.getCardId() + "-" + c.getLevel() + "-" + c.getCurExp() + "-" + maxExp + "-" + maxHp + "-" + atk + "-" + def);
										}
									}
									blrj.cs0 = cards0;
									blrj.cs1 = cards1;
									blrj.ag = md.coins;
									blrj.gm = blj.gm;
									// 玩家获得物品奖励
									blrj.ds = new ArrayList<String>();
									if (pi.brj.ds != null)
									{
										for (String drop : pi.brj.ds)
										{
											if (drop == null || "".equals(drop))
											{
												continue;
											}
											blrj.ds.add(drop);
											String[] ss = drop.split("-");
											int type = StringUtil.getInt(ss[0]);
											switch (type)
											{
												case 1:// item
													String[] temp = ss[1].split(",");
													pi.addItem(StringUtil.getInt(temp[0]), StringUtil.getInt(temp[1]));
													break;
												case 2:// equip
													pi.addEquip(StringUtil.getInt(ss[1]));
													break;
												case 3:// card
													temp = ss[1].split(",");
													cardIds.add(StringUtil.getInt(temp[0]));
													pi.addCard(StringUtil.getInt(temp[0]), StringUtil.getInt(temp[1]));
													break;
												case 4:// skill
													pi.addSkill(StringUtil.getInt(ss[1]), 1);
													break;
												case 5:// passiveSkill
													pi.addPassiveSkill(StringUtil.getInt(ss[1]));
													break;
											}
										}
									}
									if (cardIds.size() > 0)
									{
										pi.getNewUnitSkill(cardIds);
									}
									// 记录挑战次数,2位字符来表示
									if (md != null)
									{
										if (md.missiontype == 1)
										{
											String times = pi.player.getTimes1();
											int beginIndex = (sequence - 1) * 2;
											int endIndex = beginIndex + 2;
											String t = times.substring(beginIndex, endIndex);
											int num = StringUtil.getInt(t);
											String s = (num + 1) + "";
											if (s.length() == 1)
											{
												s = "0" + s;
											}
											times = times.substring(0, beginIndex) + s + times.substring(endIndex, times.length());
											pi.player.setTimes1(times);
										}
										else
										{
											String times = pi.player.getTimes2();
											int beginIndex = (sequence - 1) * 2;
											int endIndex = beginIndex + 2;
											String t = times.substring(beginIndex, endIndex);
											int num = StringUtil.getInt(t);
											String s = (num + 1) + "";
											if (s.length() == 1)
											{
												s = "0" + s;
											}
											times = times.substring(0, beginIndex) + s + times.substring(endIndex, times.length());
											pi.player.setTimes2(times);
										}
									}
								}
								else if (blj.r == 2)
								{
									// 战斗失败
									// 角色卡,格式:cardId-level-curExp-maxExp-hp-atk-def
									List<String> cards0 = new ArrayList<String>();
									for (Card c : pi.getCardGroup().cards)
									{
										if (c != null)
										{
											CardData cd = CardData.getData(c.getCardId());
											// 战前
											int maxExp = 0;
											CardExpData ced = CardExpData.getData(c.getLevel() + 1);
											if (cd != null && ced != null)
											{
												maxExp = ced.starexps[cd.star - 1];
											}
											int maxHp = (int) Statics.getCardSelfMaxHp(c.getCardId(), c.getLevel(), c.getBreakNum());
											int atk = (int) Statics.getCardSelfMaxAtk(cd.id, c.getLevel(), c.getBreakNum());
											int def = (int) Statics.getCardSelfMaxDef(cd.id, c.getLevel(), c.getBreakNum());
											cards0.add(c.getCardId() + "-" + c.getLevel() + "-" + c.getCurExp() + "-" + maxExp + "-" + maxHp + "-" + atk + "-" + def);
										}
									}
									blrj.cs0 = cards0;
								}
								// 是否需要添加支援玩家为好友
								if (pi.needAddHelperAsFriend)
								{
									blrj.hi = pi.helperPlayerId;
									blrj.hn = pi.helperPlayerName;
									pi.helperPlayerId = 0;
									pi.helperPlayerName = "";
								}
								// 新手引导--战斗
								if (pi.player.getNewPlayerType() < 7)// 修改数据库中标识
								{
									pi.player.setNewPlayerType(pi.player.getNewPlayerType() + 1);
								}
								// 新手引导-好友、第一次进入第二区域第一关时110201
								if (pi.player.getNewPlayerType() == 12 && pi.brj.md == 110201)
								{
									pi.player.setNewPlayerType(pi.player.getNewPlayerType() + 1);
								}
								// 记录
								if (blj.r == 1)
								{
									playlogger.info("|区服：" + Cache.getInstance().serverId + "|玩家：" + pi.player.getId() + "|" + pi.player.getName() + "|推图结束|" + pi.brj.md + "|成功");
								}
								else
								{
									playlogger.info("|区服：" + Cache.getInstance().serverId + "|玩家：" + pi.player.getId() + "|" + pi.player.getName() + "|推图结束|" + pi.brj.md + "|失败");
								}
							}
							else
							{
								// 校验出错,写入日志
								blrj.errorCode = 2;
								battleCheckLogger.error("校验出错:" + JSON.toJSONString(blj));
							}
							pi.blrj = blrj;
							pi.bNum = pi.bNum + 1;
							// 模块解锁
							int mission = pi.player.getMissionId();
							int lv = pi.player.getLevel();
							String[] s = UnLockData.getUnLockStrByMethod(mission, lv);
							blrj.s = s;
						}
						else
						{
							blrj = pi.blrj;
						}
					}
				}
				else
				{
					blrj.errorCode = -3;
				}
			}
			else
			{
				blrj.errorCode = -1;
			}
			Cache.recordRequestNum(blrj);
			String msg = JSON.toJSONString(blrj);
			// 返回结果
			logger.info("msg:" + msg);
			RequestUtil.setResponseMsg(request, msg);
			return new ModelAndView("/user/result.vm");
		}
		catch (Exception e)
		{
			// 捕获异常,删掉旧密钥,生成新密钥发给客户端
			errorlogger.error(this.getClass().getName() + "->" + Thread.currentThread().getStackTrace()[1].getMethodName() + "():", e);
			RequestUtil.removeKey(request);
			String newKey = RequestUtil.setNewKey(request);
			RequestUtil.setResult(request, newKey);
		}
		return new ModelAndView("/user/result.vm");
	}
	
	/** 迷宫战斗结束 **/
	public ModelAndView mazeBattleover(HttpServletRequest request, HttpServletResponse response)
	{
		try
		{
			// 校验密钥
			ModelAndView checkResult = RequestUtil.check(request);
			if (checkResult != null)
			{
				return checkResult;
			}
			// 获取json
			JSONObject jsonObject = RequestUtil.getJsonObject(request);
			// 获取参数
			MazeBattleLogJson mblj = JSONObject.toJavaObject(jsonObject, MazeBattleLogJson.class);
			MazeBattleLogResultJson mblrj = new MazeBattleLogResultJson();
			mblrj.r = mblj.r;
			if (mblj != null)
			{
				PlayerInfo pi = Cache.getInstance().getPlayerInfo(mblj.playerId, request.getSession());
				if (pi != null)
				{
					int bNum = mblj.bNum;
					if (pi.bNum < bNum && pi.mbrj.bNum == bNum)// 第一次请求
					{
						long time = System.currentTimeMillis();
						boolean isRight = true;
						// 概率校验
						int roll = Random.getNumber(100);
						if (roll < checkPro)
						{
							// TODO校验
						}
						logger.info("耗时:" + (System.currentTimeMillis() - time));
						// 如果校验正确,加入奖励
						if (isRight)
						{
							MazeBattleData mbd = MazeBattleData.getMazeBattleData(pi.mbrj.md);
							/** 如果胜利 **/
							// 记录每日任务进度
							
							if (mblj.r == 1)
							{
								if (mblj.type == 2)
								{
									ActivityController.updateTaskComplete(4, pi, 1);
									pi.player.addActive(4, 1);
								}
								// 战前玩家信息
								mblrj.lv0 = pi.player.getLevel();
								mblrj.ce0 = pi.player.getCurExp();
								mblrj.power0 = pi.player.getPower();
								PlayerData pd = PlayerData.getData(pi.player.getLevel() + 1);
								if (pd != null)
								{
									mblrj.me0 = pd.exp;
								}
								// 玩家获得经验
								pi.player.addExp(mbd.personexp);
								// 玩家获得金币
								int gold = (int) (mbd.coins * Float.valueOf(mblj.gm));
								pi.player.addGold((int) Cache.getGoldDropMul() * gold);
								// 战后玩家信息
								mblrj.lv1 = pi.player.getLevel();
								mblrj.ce1 = pi.player.getCurExp();
								mblrj.power1 = pi.player.getPower();
								pd = PlayerData.getData(pi.player.getLevel() + 1);
								if (pd != null)
								{
									mblrj.me1 = pd.exp;
								}
								// 战前/战后角色卡信息,格式:cardId-level-curExp-maxExp-hp-atk-def
								List<String> cards0 = new ArrayList<String>();
								List<String> cards1 = new ArrayList<String>();
								for (int i = 0; i < pi.mazes.size(); i++)
								{
									Maze maze = pi.mazes.get(i);
									if (maze.getMazeId() == mblj.map)
									{
										String[] cs = maze.getCardInfo().split(",");
										String[] breakNums = maze.getBreakInfo().split("-");
										for (int j = 0; j < cs.length; j++)
										{
											String[] cids = cs[j].split("-");
											int cid = StringUtil.getInt(cids[0]);
											int clevel = StringUtil.getInt(cids[1]);
											int breakNum = StringUtil.getInt(breakNums[j]);
											// for (Card c :
											// pi.getCardGroup().cards)
											// {
											// if (c != null)
											// {
											CardData cd = CardData.getData(cid);
											// 战前
											int maxExp = 0;
											CardExpData ced = CardExpData.getData(clevel + 1);
											if (cd != null && ced != null)
											{
												maxExp = ced.starexps[cd.star - 1];
											}
											int maxHp = (int) Statics.getCardSelfMaxHp(cid, clevel, breakNum);
											int atk = (int) Statics.getCardSelfMaxAtk(cd.id, clevel, breakNum);
											int def = (int) Statics.getCardSelfMaxDef(cd.id, clevel, breakNum);
											cards0.add(cid + "-" + clevel + "-" + 0 + "-" + maxExp + "-" + maxHp + "-" + atk + "-" + def);// 0是当前card经验
											// 角色卡获得经验
											// c.addExp(mbd.cardexp);
											// 战后
											// ced =
											// CardExpData.getData(c.getLevel()
											// + 1);
											// if (cd != null && ced != null)
											// {
											// maxExp = ced.starexps[cd.star -
											// 1];
											// }
											// maxHp = (int)
											// Statics.getCardSelfMaxHp(c.getCardId(),
											// c.getLevel(), c.getBreakNum());
											// atk = (int)
											// Statics.getCardSelfMaxAtk(cd.id,
											// c.getLevel(), c.getBreakNum());
											// def = (int)
											// Statics.getCardSelfMaxDef(cd.id,
											// c.getLevel(), c.getBreakNum());
											// cards1.add(c.getCardId() + "-" +
											// c.getLevel() + "-" +
											// c.getCurExp() + "-" + maxExp +
											// "-" + maxHp + "-" + atk + "-" +
											// def);
											// }
											// }
										}
									}
								}
								
								mblrj.cs0 = cards0;
								mblrj.cs1 = cards0;
								mblrj.ag = mbd.coins;
								mblrj.gm = mblj.gm;
								// 玩家获得物品奖励
								mblrj.ds = new ArrayList<String>();
								List<Integer> cardIds = new ArrayList<Integer>();
								boolean bossDrop = false;
								if (mblj.type == 2)// 记录boss掉落的碎片
								{
									bossDrop = true;
								}
								boolean isin = false;
								HashMap<Integer, String> dropMap = new HashMap<Integer, String>();
								if (pi.player.getMazeBossDrop() != null && pi.player.getMazeBossDrop().length() > 0)
								{
									String[] mDrop = pi.player.getMazeBossDrop().split("&");
									for (int i = 0; i < mDrop.length; i++)
									{
										if (mDrop[i] != null && mDrop[i].length() > 0)
										{
											String[] temp = mDrop[i].split("-");
											if (StringUtil.getInt(temp[0]) == mbd.map)
											{
												for (int j = 1; j < temp.length; j++)
												{
													if (!dropMap.containsKey(StringUtil.getInt(temp[j])))
													{
														dropMap.put(StringUtil.getInt(temp[j]), temp[j]);
													}
												}
												isin = true;
												break;
											}
										}
									}
								}
								
								if (pi.mbrj.s != null)
								{
									for (String drop : pi.mbrj.s)
									{
										if (drop == null || "".equals(drop))
										{
											continue;
										}
										else
										{
											String[] temp = drop.split("-");
											mblrj.ds.add(temp[0] + "-" + temp[1]);
											if (StringUtil.getInt(temp[0]) == 3)
											{
												String[] str = temp[1].split(",");
												cardIds.add(StringUtil.getInt(str[0]));
											}
											if (StringUtil.getInt(temp[0]) == 1 && bossDrop)// 碎片
											{
												String[] str = temp[1].split(",");
												if (!isin)
												{
													if (pi.player.getMazeBossDrop() == null || pi.player.getMazeBossDrop().length() == 0)
													{
														pi.player.setMazeBossDrop(mbd.map + "-" + str[0]);
													}
													else
													{
														pi.player.setMazeBossDrop(pi.player.getMazeBossDrop() + "&" + mbd.map + "-" + str[0]);
													}
												}
												else
												{
													String[] mDrop = pi.player.getMazeBossDrop().split("&");
													for (int i = 0; i < mDrop.length; i++)
													{
														if (mDrop[i] != null && mDrop[i].length() > 0)
														{
															String[] temp1 = mDrop[i].split("-");
															if (StringUtil.getInt(temp1[0]) == mbd.map)
															{
																if (!dropMap.containsKey(StringUtil.getInt(str[0])))
																{
																	mDrop[i] = mDrop[i] + "-" + str[0];
																	dropMap.put(StringUtil.getInt(str[0]), str[0]);
																}
																break;
															}
														}
													}
													String string = "";
													for (int k = 0; k < mDrop.length; k++)
													{
														if (string == null || string.length() == 0)
														{
															string = mDrop[k];
														}
														else
														{
															string = string + "&" + mDrop[k];
														}
													}
													pi.player.setMazeBossDrop(string);
												}
											}
											Statics.getReward(StringUtil.getInt(temp[0]), temp[1], pi);
										}
									}
								}
								
								if (cardIds.size() > 0)
								{
									pi.getNewUnitSkill(cardIds);
								}
								// 开始冷却时间
								if (mblj.type == 2)// boss胜利
								{
									pi.mazecdtime = System.currentTimeMillis();
									String firstentry = pi.player.getMazeFirstEntry();// 修改首次进入迷宫boss固定掉落标识
									if (firstentry == null || firstentry.length() == 0)
									{
										firstentry = mblj.map + "";
									}
									else
									{
										HashMap<Integer, String> map = new HashMap<Integer, String>();
										String[] fe = firstentry.split("&");
										for (int m = 0; m < fe.length; m++)
										{
											if (fe[m] != null && fe[m].length() > 0)
											{
												map.put(StringUtil.getInt(fe[m]), fe[m]);
											}
											
										}
										if (!map.containsKey(mblj.map))
										{
											firstentry = firstentry + "&" + mblj.map;
										}
									}
									pi.player.setMazeFirstEntry(firstentry);
								}
								
							}
							else
							{
								// 战斗失败
								// 角色卡,格式:cardId-level-curExp-maxExp-hp-atk-def
								List<String> cards0 = new ArrayList<String>();
								for (Card c : pi.getCardGroup().cards)
								{
									if (c != null)
									{
										CardData cd = CardData.getData(c.getCardId());
										// 战前
										int maxExp = 0;
										CardExpData ced = CardExpData.getData(c.getLevel() + 1);
										if (cd != null && ced != null)
										{
											maxExp = ced.starexps[cd.star - 1];
										}
										int maxHp = (int) Statics.getCardSelfMaxHp(c.getCardId(), c.getLevel(), c.getBreakNum());
										int atk = (int) Statics.getCardSelfMaxAtk(cd.id, c.getLevel(), c.getBreakNum());
										int def = (int) Statics.getCardSelfMaxDef(cd.id, c.getLevel(), c.getBreakNum());
										cards0.add(c.getCardId() + "-" + c.getLevel() + "-" + c.getCurExp() + "-" + maxExp + "-" + maxHp + "-" + atk + "-" + def);
									}
								}
								mblrj.cs0 = cards0;
							}
							// 跟新玩家迷宫进度
							String[] mazes = pi.player.getMaze().split(",");
							for (int i = 0; i < mazes.length; i++)
							{
								String[] maze = mazes[i].split("-");
								if (maze[0] != null && maze[0].length() > 0)
								{
									if (StringUtil.getInt(maze[0]) == mblj.map)
									{
										MazeData mData = MazeData.getMazeData(mblj.map);
										// boss战
										if (mblj.type == 2)
										{
											if (pi.player.getNewPlayerType() == 17)
											{
												pi.player.setNewPlayerType(pi.player.getNewPlayerType() + 1);
												pi.addSkill(13021, 1);
											}
											if (pi.mazes != null)
											{
												for (Maze maze2 : pi.mazes)
												{
													if (maze2.getMazeId() == mblj.map)
													{
														pi.mazes.remove(maze2);
													}
												}
											}
											// 每次迷宫结束扣除体力
											if (pi.player.getNewPlayerType() != 17)
											{
												pi.player.removePower(mData.energy);
											}
											// 每次迷宫结束清空血瓶购买次数
											if (pi.player.getBloodBuffNum() > 0)
											{
												pi.player.setBloodBuffNum(0);
											}
											maze[1] = 0 + "";
											maze[2] = StringUtil.getInt(maze[2]) + 1 + "";
											mazes[i] = maze[0] + "-" + maze[1] + "-" + maze[2] + "-" + maze[3];// 初始位置为0
											if (mblj.r == 1)// 胜利
											{
												mblrj.state = 0;
											}
											else if (mblj.r == 2)// 失败
											{
												mblrj.state = StringUtil.getInt(maze[1]);
											}
										}
										// 普通战
										if ((mblj.type == 1 || mblj.type == 3) && mblj.r == 1)// 胜利
										{
											if (pi.mazes != null)
											{
												String[] ss = mblj.cb.split("&");
												for (int j = 0; j < pi.mazes.size(); j++)
												{
													Maze m = pi.mazes.get(j);
													if (m.getMazeId() == mblj.map)
													{
														String strblood = "";
														String[] card = m.getCardInfo().split(",");
														String[] s3 = m.getMaxbloodInfo().split("-");
														for (int k = 0; k < card.length; k++)
														{
															String[] s = card[k].split("-");
															String[] s2 = ss[k].split("-");
															if (StringUtil.getInt(s[0]) == StringUtil.getInt(s2[0]))
															{
																if ("".equals(strblood))
																{
																	if (StringUtil.getInt(s2[1])>StringUtil.getInt(s3[k]) || StringUtil.getInt(s2[1])<=0)
																	{
																		errorlogger.info("返回迷宫战斗血数据错误!");
																	}
																	strblood = s2[1];
																}
																else
																{
																	if (StringUtil.getInt(s2[1])>StringUtil.getInt(s3[k]) || StringUtil.getInt(s2[1])<=0)
																	{
																		errorlogger.info("返回迷宫战斗血数据错误!");
																	}
																	strblood = strblood + "-" + s2[1];
																}
															}
														}
														m.setBloodInfo(strblood);
														pi.mazes.remove(j);
														pi.mazes.add(m);
														break;
													}
												}
											}
											maze[1] = pi.mbrj.state + "";
											mazes[i] = maze[0] + "-" + maze[1] + "-" + maze[2] + "-" + maze[3];
											mblrj.state = pi.mbrj.state;
										}
										else if ((mblj.type == 1 || mblj.type == 3) && mblj.r == 2)// 失败
										{
											if (pi.player.getNewPlayerType() == 17)
											{
												pi.player.setNewPlayerType(pi.player.getNewPlayerType() + 1);
												pi.addSkill(13021, 1);
											}
											if (pi.mazes != null)
											{
												for (Maze maze2 : pi.mazes)
												{
													if (maze2.getMazeId() == mblj.map)
													{
														pi.mazes.remove(maze2);
													}
												}
											}
											// 每次迷宫结束扣除体力
											if (pi.player.getNewPlayerType() != 17)
											{
												pi.player.removePower(mData.energy);
											}
											// 每次迷宫结束清空血瓶购买次数
											if (pi.player.getBloodBuffNum() > 0)
											{
												pi.player.setBloodBuffNum(0);
											}
											mblrj.state = StringUtil.getInt(maze[1]);
											maze[1] = 0 + "";
											maze[2] = StringUtil.getInt(maze[2]) + 1 + "";
											mazes[i] = maze[0] + "-" + maze[1] + "-" + maze[2] + "-" + maze[3];
										}
										break;
									}
								}
							}
							String newStr = "";
							for (int j = 0; j < mazes.length; j++)
							{
								if (mazes[j] != null && mazes[j].length() > 0)
								{
									if (newStr == null || newStr.length() == 0)
									{
										newStr = mazes[j];
									}
									else
									{
										newStr = newStr + "," + mazes[j];
									}
								}
								else
								{
									continue;
								}
							}
							pi.player.setMaze(newStr);
							playlogger.info("|玩家" + pi.player.getId() + "迷宫战斗结束");
						}
						else
						{
							// 校验出错,写入日志
							mblrj.errorCode = 2;
							battleCheckLogger.info("校验出错:" + JSON.toJSONString(mblrj));
						}
						pi.mblrj = mblrj;
						pi.bNum = pi.bNum + 1;
						mblrj.map = mblj.map;
						mblrj.type = mblj.type;
					}
					else
					{
						mblrj = pi.mblrj;
					}
				}
				else
				{
					mblrj.errorCode = -3;
				}
			}
			else
			{
				mblrj.errorCode = -1;
			}
			Cache.recordRequestNum(mblrj);
			String msg = JSON.toJSONString(mblrj);
			// 返回结果
			logger.info("msg:" + msg);
			RequestUtil.setResponseMsg(request, msg);
			return new ModelAndView("/user/result.vm");
		}
		catch (Exception e)
		{
			// 捕获异常,删掉旧密钥,生成新密钥发给客户端
			errorlogger.error(this.getClass().getName() + "->" + Thread.currentThread().getStackTrace()[1].getMethodName() + "():", e);
			RequestUtil.removeKey(request);
			String newKey = RequestUtil.setNewKey(request);
			RequestUtil.setResult(request, newKey);
		}
		return new ModelAndView("/user/result.vm");
	}
	
	/** 奖励发放到背包 **/
	private static void bonusAward(int type, String award, PlayerInfo pi)
	{
		
		Statics.getReward(type, award, pi);
	}
	
	public static void main(String[] args)
	{
		try
		{
			BinReader br = new BinReader();
			br.localRES_DIR();
			br.readAllData();
			FileInputStream fis = new FileInputStream(new File("D://test//battlelog.txt"));
			int length = fis.available();
			byte[] bytes = new byte[length];
			fis.read(bytes);
			// BattleLogJson
			// battleLog=JSONObject.toJavaObject(JSON.parseObject(new
			// String(bytes)), BattleLogJson.class);
			// boolean isRight=StaticMethod.checkBattleLog(battleLog,logger);
			// System.out.println("isRight:"+isRight+",数据大小:"+(length/1024f)+"KB");
			
			String key = EncryptAndDecipher.generateKey();
			String s = new String(bytes);
			System.out.println("压缩前:" + s.length());
			String temp = StringUtil.compressByGZIP(s);
			System.out.println("压缩后:" + temp.length());
			String s2 = StringUtil.uncompressByGZIP(temp);
			System.out.println("解压缩后:" + s2.length());
			System.out.println("s==s2:" + s2.equals(s));
			s = EncryptAndDecipher.encrypt(key, temp);
			System.out.println("s:" + s.length());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
}
